<?php

	class bEmail {
	
		private $rSocket;
		private $sServerKey;
		
		private $xEmail;
		private $xHeadlines;
		
		private $sUsername;
		private $sPassword;
		private $bIsLoggedIn;
		
		private $nBufferLength;
		private $nPageLength;
		
		public function __construct($xData = null) {
			$sHost = isset($xData->Host) ? $xData->Host : "mail.example.com";
			$sPort = isset($xData->Port) ? $xData->Port : 110;
			
			$this->nPageLength = isset($xData->Page) ? $xData->Page : 20;
			$this->nBufferLength = isset($xData->Buffer) ? $xData->Buffer : 512;
			
			$s = "<x><Host>{$sHost}</Host><Port>{$sPort}</Port></x>";
			$x = simplexml_load_string($s);
			$this->xEmail = $x;
		}
		
		public function __destruct() {
			if(!is_null($this->rSocket)) {
				$this->Release($this->rSocket);
			}
		}
		
		private function ConnectData() {
			return array(
				$this->xEmail->Host,
				$this->xEmail->Port,
				100,
				"You have an error connecting to the mail server."
			);
		}
		
		protected function Connect() {
			list($sHost, $sPort) = $this->ConnectData();
			
			$rSocket = fsockopen($sHost, (int)$sPort, $sErrorNum, $sErrorTxt);
			$this->rSocket =& $rSocket;
			
			if (!$rSocket) { throw new Exception("Could not connect to the correct server and/or port:{$sErrorTxt}", (1000 + (int)$sErrorNum)); }
			
			$sData = fgets ($rSocket, $this->nBufferLength);
	
			return is_ok($sData);
		}
		
		protected function Release($rSocket = null) {
			if(is_null($rSocket)) { 
				$rSocket =& $this->rSocket; 
			}
			
			if(!is_null($rSocket)) {
				fputs ($rSocket, "QUIT\n");
				fclose ($rSocket);
				$rSocket = null;
			}
			
			return true;
		}
		
		public function SetUser($sUsername, $sPassword, $rSocket=null) {
			if(is_null($rSocket)) { $this->Connect(); $rSocket =& $this->rSocket; }
			
			list($this->sUsername, $this->sPassword) = func_get_args();
	
			// Username
			fputs($rSocket, "USER {$sUsername}\r\n");
			$sResponse = fgets($rSocket, 50);
			if(!($this->bIsLoggedIn = is_ok($sResponse))) { $this->Release(); return false; }
			
			// Password
			fputs ($rSocket, "PASS {$sPassword}\r\n");
			$sResponse = fgets($rSocket, 50);
			if(!($this->bIsLoggedIn = is_ok($sResponse))) { $this->Release(); return false; }
			
			// check for success code
			return $this->bIsLoggedIn;	
		}
		
		/**
		* Pulls the subject, from and date from an email address and places it into an simple xml object
		*/
		public function GetHeadlines($nPage=1, $nPageLength=null, $nLines=0, $rSocket=null) {
			if(is_null($nPageLength)) { $nPageLength = $this->nPageLength; }
			if(is_null($rSocket)) { $rSocket =& $this->rSocket; }
			
			$xReturn = simplexml_load_string("<xreturn/>");
		
			if($this->bIsLoggedIn) {
				
				fputs($rSocket, "LIST \n");
			
				$sList = "";
				while(!ereg("^\.\r\n", $sResponse)) {
	//				echo "...<br /><br />".$sResponse;
					$sList .= $sResponse = fgets($rSocket, $this->nBufferLength);
					if(ereg("^\.\r\n", $sResponse)) break;
				}
				$aList = explode("\n", $sList);
				$sShifted = array_shift($aList);
	
				foreach($aList as $sListInformation) {
				
					if(preg_match('/\+OK (\d+) /', $sListInformation, $aMatch))
					{
					} else if(preg_match('/(\d+) /', $sListInformation, $aMatch))
					{				
					} else { //throw new Exception('You did not get a valid LIST response', 3000); 
						
						continue;
					}
					
					$nMessages = $aMatch[1];
					$nEnd = $nPageLength += $nStart = (((abs($nPage)-1) * $nPageLength) + (($nPage > 0) ? 1 : -$nMessages));
		
					$nStart = ($nStart < 1 ? 1 : ($nStart > $nMessages ? $nMessages - $nPageLength : $nStart));
					$nEnd = ($nEnd > $nMessages ? $nMessages : ($nEnd < 1 ? $nPageLength : $nEnd));
				
					for($i=$nStart; $i <= $nEnd; $i++) {
						fputs($rSocket, "TOP {$i} {$nLines}\n");
						
						$sResponse = $sTop = "";
						while(!ereg("^\.\r\n", $sResponse)) {
							$sTop .= $aChunk[] = $sResponse = fgets($rSocket, $this->nBufferLength);
							if(ereg("^\.\r\n", $sResponse)) break;
						}
						
		
						if(is_ok($aChunk[0])) {
							$m = explode("\n", $sTop);
							$a = array_map(create_function('$v', 'foreach(array("Date: ","Subject: ","From: ") as $s) { if(!(strpos($v, $s) === false)) { return $v; }}'), $m);
							$aResponse = array_filter( $a, create_function('$v', 'return (bool)$v;'));
						
							$xMessageNode = $xReturn->AddChild('message');
							
							foreach($aResponse as $sLine) {
								$n = strpos($sLine, ':');
								$sKey = substr(strtolower($sLine), 0, $n);
								$sValue = substr($sLine, ($n+1), strlen($sLine));
								$xMessageNode->AddChild($sKey, $sValue);
								
							}
						} else { throw new Exception('You cannot read messages.', 4000); }
					}
				}
		    }
		    
			return $xReturn;
		}
		
		/**
		* Reads an email from the system
		*/
		public function GetMessage($nMessage, $rSocket=null) {
			if(is_null($rSocket)) { $rSocket =& $this->rSocket; }
			
			fputs($rSocket, "TOP {$nMessage} -1\r\n");
			$sHeaders = fgets($rSocket, $this->nBufferLength);
			
			fputs($rSocket, "RETR {$nMessage}\r\n");
			
			$sLine ='';
			while(!ereg("^\.\r\n", $sResponse =fgets($rSocket, $this->nBufferLength))) {
				$sLine .= $sResponse;
				if(ereg("^\.\r\n", $sResponse)) break;
			}
			
			$sMessage = $sLine;
	
			return $sMessage;
		}
	}
	
	function is_ok($sString) { return (substr($sString, 0, 3) == "+OK"); }
?>
